(function (fruit, ui, position, util, dom) {
    var TooltipPositionMap = {
        'tt_outerRightTop': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.width + targetBound.left - docScrollXY.scrollX + optionOffset.offsetX + 15,
                top: Math.max(targetBound.top + targetBound.height / 2 - docScrollXY.scrollY + optionOffset.offsetY - 48, 2)
            };
        },
        'tt_outerRightCenter': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.width + targetBound.left - docScrollXY.scrollX + optionOffset.offsetX + 15,
                top: targetBound.top + targetBound.height / 2 - elBound.height / 2 - docScrollXY.scrollY + optionOffset.offsetY + 0
            };
        },
        'tt_outerRightBottom': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.width + targetBound.left - docScrollXY.scrollX + optionOffset.offsetX + 15,
                top: targetBound.top + targetBound.height / 2 - docScrollXY.scrollY - elBound.height + optionOffset.offsetY + 33
            };
        },

        'tt_outerLeftTop': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left - elBound.width - docScrollXY.scrollX - optionOffset.offsetX - 15,
                top: Math.max(targetBound.top + targetBound.height / 2 - docScrollXY.scrollY + optionOffset.offsetY - 48, 2)
            };
        },
        'tt_outerLeftCenter': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left - elBound.width - docScrollXY.scrollX - optionOffset.offsetX - 15,
                top: targetBound.top + targetBound.height / 2 - elBound.height / 2 - docScrollXY.scrollY + optionOffset.offsetY + 0
            };
        },
        'tt_outerLeftBottom': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left - elBound.width - docScrollXY.scrollX - optionOffset.offsetX - 15,
                top: targetBound.top + targetBound.height / 2 - docScrollXY.scrollY - elBound.height + optionOffset.offsetY + 33
            };
        },

        'tt_outerBottom': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - elBound.width / 2 - docScrollXY.scrollX + optionOffset.offsetX,
                top: targetBound.top + targetBound.height - docScrollXY.scrollY + optionOffset.offsetY + 12
            };
        },
        'tt_outerBottomLeft': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - docScrollXY.scrollX + optionOffset.offsetX - 30,
                top: targetBound.top + targetBound.height - docScrollXY.scrollY + optionOffset.offsetY + 12
            };
        },
        'tt_outerBottomRight': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - elBound.width - docScrollXY.scrollX + optionOffset.offsetX + 22,
                top: targetBound.top + targetBound.height - docScrollXY.scrollY + optionOffset.offsetY + 12
            };
        },

        'tt_outerTop': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - elBound.width / 2 - docScrollXY.scrollX - optionOffset.offsetX,
                top: targetBound.top - elBound.height - docScrollXY.scrollY - optionOffset.offsetY - 12
            };
        },
        'tt_outerTopLeft': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - docScrollXY.scrollX - optionOffset.offsetX - 30,
                top: targetBound.top - elBound.height - docScrollXY.scrollY - optionOffset.offsetY - 12
            };
        },
        'tt_outerTopRight': function (elBound, targetBound, docScrollXY, optionOffset) {
            return {
                left: targetBound.left + targetBound.width / 2 - elBound.width - docScrollXY.scrollX - optionOffset.offsetX + 22,
                top: targetBound.top - elBound.height - docScrollXY.scrollY - optionOffset.offsetY - 12
            };
        }

    };


    var DirectionMap = {
        "right": ['tt_outerRightTop', 'tt_outerRightCenter', 'tt_outerRightBottom', 'tt_outerLeftTop', 'tt_outerLeftCenter', 'tt_outerLeftBottom'],
        "left": ['tt_outerLeftTop', 'tt_outerLeftCenter', 'tt_outerLeftBottom', 'tt_outerRightTop', 'tt_outerRightCenter', 'tt_outerRightBottom'],
        "center": ['tt_outerRightCenter', 'tt_outerLeftCenter', 'tt_outerLeftTop', 'tt_outerLeftBottom', 'tt_outerRightTop', 'tt_outerRightBottom'],
        "top": ['tt_outerTop', 'tt_outerTopLeft', 'tt_outerTopRight', 'tt_outerBottom', 'tt_outerBottomLeft', 'tt_outerBottomRight'],
        "bottom": ['tt_outerBottom', 'tt_outerBottomLeft', 'tt_outerBottomRight', 'tt_outerTop', 'tt_outerTopLeft', 'tt_outerTopRight'],
        'auto': ['tt_outerRightCenter', 'tt_outerLeftCenter', 'tt_outerLeftTop', 'tt_outerLeftBottom', 'tt_outerRightTop', 'tt_outerRightBottom', 'tt_outerBottom', 'tt_outerBottomLeft', 'tt_outerBottomRight', 'tt_outerTop', 'tt_outerTopLeft', 'tt_outerTopRight']
    }


    ui.define('fruit.ui.Tooltip', fruit.ui.Popup, {
        view: {
            name: 'popup',
            props: {
                'class': 'fruit f-tooltip',
                position: ""
            },
            content: [
                {
                    name: 'arrow',
                    tag: 'span',
                    props: {
                        'class': 'f-tooltip-arrow',
                        'role': 'arrow'
                    }
                },
                {
                    name: 'body',
                    //region: true,
                    content: '{#content}'
                }
            ]
        },
        properties: {
            content: {
                value: null,
                observable: true
            }
        },
        methods: {
            onInit: function () {
                this.inherited();
                util.each(TooltipPositionMap, function (value, key) {
                    this.registerPositionMap(key, value);
                }, this);

            },
            open: function (opts) {
                this.inherited(opts);

                var final_position;
                var positionMap = position.positionMap;
                var direction = opts.position || "auto";

                // fix getbound bug
                position.setWidth(this._element,"auto");
                var elementRect = position.getBound(this._element);
                position.setOuterWidth(this._element,elementRect.width);

                // hit test position find most fit position
                util.find(DirectionMap[direction], function (inPosition) {
                    if (positionMap[inPosition]) {
                        final_position = inPosition;
                        return this.__hitTest(inPosition);
                    }
                }, this);
                // add attr & class
                this.removeClass(this.getAttribute("position") || "");
                this.addClass(final_position);
                this.setAttribute("position", final_position);
            },
            __hitTest: function (inPosition) {
                var docRect = fruit.position.getDocRect();
                this.setDirection(inPosition);
                var elementRect = position.getBound(this._element);

                //make sure it visible
                return elementRect.left >= docRect.scrollX
                    && elementRect.top >= docRect.scrollY
                    && elementRect.left + elementRect.width <= docRect.width + docRect.scrollX
                    && elementRect.top + elementRect.height <= docRect.height + docRect.scrollY;

            }
        }
    });
})(fruit, fruit.ui, fruit.position, fruit.util, fruit.dom);